package com.service.mybatis.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.common.utils.constant.Constants;
import com.common.utils.tool.UserUtil;
import com.common.model.pojo.Keyword;
import com.common.model.pojo.Order;
import com.common.model.pojo.Query;
import com.service.mybatis.pojo.SuperEntity;
import com.service.mybatis.service.ISuperService;

import java.util.List;
import java.util.Map;

/**
 * mybatis-plus 分页工具类
 * @author zhaoj
 * @create 2021/9/1
 */
public class Condition {
    /**
     * 转化成mybatis plus中的Page
     *
     * @param query 查询条件
     * @return IPage
     */
    public static <T> Page<T> getPage(Query query) {
        Page<T> page = new Page<>(Convert.toInt(query.getCurrent(), 1), Convert.toInt(query.getSize(), Integer.MAX_VALUE));
        page.setSearchCount(true);
        page.setOptimizeCountSql(true);
        return page;
    }

    /**
     * 新版mybatis 不支持这个排序方式
     * @param query
     * @param page
     */
    @Deprecated
    public static <T> void addOrder(Query query, Page<T> page) {
        List<Order> orders = query.filterNullOrders();
        if(CollUtil.isEmpty(orders)) {
            page.addOrder(OrderItem.desc(SuperEntity.CREATE_TIME_FIELD));
        } else {
            for (Order order : orders) {
                if (order.getAsc()){
                    page.addOrder(OrderItem.asc(StrUtil.toUnderlineCase(order.getOrderField())));
                } else {
                    page.addOrder(OrderItem.desc(StrUtil.toUnderlineCase(order.getOrderField())));
                }
            }
        }
    }

    /**
     * 转化成mybatis plus中的Page
     *
     * @param query 查询条件
     * @return IPage
     */
    public static <T> QueryWrapper<T> getQueryWrapper(Query query) {
        return getQueryWrapperAndUserName(query, null);
    }

    /**
     * 转化成mybatis plus中的Page 带用户名查询
     *
     * @param query 查询条件
     * @return IPage
     */
    public static <T> QueryWrapper<T> getQueryWrapperAndUserName(Query query, String userKey) {
        QueryWrapper<T> qw = new QueryWrapper<>();
        addUserNameLike(query, userKey, qw);
        addOrder(query, qw);
        addKeyword(query, qw);
        addParams(query, qw);
        return qw;
    }

    /**
     * 按照用户名模糊查询
     * @param query
     * @param userKey
     * @param qw
     * @param <T>
     */
    private static <T> void addUserNameLike(Query query, String userKey, QueryWrapper<T> qw) {
        if (StrUtil.isNotBlank(userKey)){
            Keyword keywordByFiledName = query.getKeywordByFiledName(userKey);
            if (keywordByFiledName != null ){
                List<String> ids = UserUtil.like(keywordByFiledName.getKeyword());
                if (CollUtil.isNotEmpty(ids)){
                    qw.in(userKey, ids);
                } else {
                    qw.eq("1", "2");
                }
            }
            query.getKeywords().remove(keywordByFiledName);
        }
    }

    /**
     * 添加排序
     * @param query
     * @param qw
     * @param <T>
     */
    public static <T> void  addOrder(Query query, QueryWrapper<T> qw) {
        List<Order> orders = query.filterNullOrders();
        if(CollUtil.isEmpty(orders)) {
            qw.orderByDesc(SuperEntity.CREATE_TIME_FIELD);
        } else {
            for (Order order : orders) {
                if (order.getAsc()){
                    qw.orderByAsc(StrUtil.toUnderlineCase(order.getOrderField()));
                } else {
                    qw.orderByDesc(StrUtil.toUnderlineCase(order.getOrderField()));
                }
            }
        }

    }
    /**
     * 添加关键字查询
     * @param query
     * @param qw
     * @param <T>
     */
    public static <T> void  addKeyword(Query query, QueryWrapper<T> qw) {
        List<Keyword> keywords = query.filterNullKeywords();
        if(CollUtil.isEmpty(keywords)) {
        } else {
            for (Keyword keyword : keywords) {
                qw.like(StrUtil.isNotEmpty(keyword.getKeyword()),
                        StrUtil.toUnderlineCase(keyword.getKeywordField()),
                        convertSpecialChar(keyword.getKeyword()));
            }
        }

    }

    /**
     * 值匹配查询
     * @param query
     * @param <T>
     */
    public static <T> void addParams(Query query, QueryWrapper<T> qw) {
        Map<String, String> params = query.getParams();
        if(CollUtil.isEmpty(params)) {
        } else {
            for (Map.Entry<String, String> param : params.entrySet()) {
                qw.eq(StrUtil.isNotBlank(param.getValue()) ,
                        StrUtil.toUnderlineCase(param.getKey()),
                        convertSpecialChar(param.getValue()));
            }
        }

    }

    /**
     * 获取mybatis plus中的QueryWrapper
     *
     * @param entity 实体
     * @param <T>    类型
     * @return QueryWrapper
     */
    public static <T> QueryWrapper<T> getQueryWrapper(T entity) {
        return new QueryWrapper<>(entity);
    }

    /**
     * 指定数据库字段
     * @param <T>
     * @return
     */
    public static <T> QueryWrapper<T> getQueryWrapper(String filedName, String keyword) {
        QueryWrapper<T> qw = new QueryWrapper<>();
        qw.like(StrUtil.isNotEmpty(keyword), filedName, convertSpecialChar(keyword));
        return qw;
    }


    /**
     * 指定数据库字段
     * @return
     */
    public static <T> QueryWrapper<T> getNameQueryWrapper(String filedName, String keyword) {
        if(StrUtil.isNotEmpty(filedName)) {
            return getQueryWrapper(StrUtil.toUnderlineCase(filedName), keyword);
        }
        return getQueryWrapper(ISuperService.NAME, keyword);
    }

    /**
     * 转义特殊字符
     */
    public static String convertSpecialChar(String keyword){
        if(StrUtil.isEmpty(keyword)) {
            return Constants.EMPTY;
        }
        String[] keys = new String[]{Constants.INTERVAL, Constants.PERCENT};
        String result = keyword;
        for (String k : keys) {
            result = StrUtil.replaceChars(result, k, "\\" + k);
        }
        return result;
    }
}
